package de.staxx6.bomber;

import java.util.ArrayList;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;

public class GameState extends AbstractAppState {
	
	/* Engine Variables */
	private ViewPort viewPort;
	private Node rootNode;
	private Node guiNode;
	private FlyByCamera flyCam;
	private Camera cam;
	private Node localRootNode = new Node("Start Screen RootNode");
	private Node localGuiNode = new Node("Start Screen GuiNode");
	private AppStateManager stateManager;
	
	public static AssetManager ASSETMANAGER;
	public static InputManager INPUTMANAGER;
	
	/* Game Variables */
	public static int FIELDSIZE = 17; // only quadrat fields and x > 4
	public static int PLAYERNUMBER = 4; // 2 - 4
	public static float FIELDBRICKDENSITY = 0.1f; // 0.1f - 1f | 0.7 is good standard
	public static boolean ISRUNNING = true;
	
	/* Class Variables */
	private Field field;
	private ArrayList<Player> playerList;
	
	public static BulletAppState BULLETAPPSTATE;
	
	public GameState(SimpleApplication app) {
		this.rootNode = app.getRootNode();
		this.viewPort = app.getViewPort();
		this.guiNode = app.getGuiNode();
		this.flyCam = app.getFlyByCamera();
		this.cam = app.getCamera();
		this.stateManager = app.getStateManager();
		ASSETMANAGER = app.getAssetManager();
		INPUTMANAGER = app.getInputManager();
	}
	
	public void initialize(AppStateManager stateManager, Application app) {
		System.out.println("GameState!");
		super.initialize(stateManager, app);

		
		viewPort.setBackgroundColor(ColorRGBA.Black);
		flyCam.setMoveSpeed(20);
		flyCam.setEnabled(false);
	}
	
	private void initField() {		
		BULLETAPPSTATE = new BulletAppState();
		stateManager.attach(BULLETAPPSTATE);
		//BULLETAPPSTATE.getPhysicsSpace().enableDebug(ASSETMANAGER);
		
		field = new Field(FIELDSIZE);
		localRootNode.attachChild(field.getNode());
		/* CAM */
		cam.setLocation(new Vector3f(FIELDSIZE / 2 + 1f, FIELDSIZE / 2 + 1f, FIELDSIZE * 1.35f));
		
		CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(field.getNode());
		RigidBodyControl physic = new RigidBodyControl(sceneShape, 0.0f);
		field.getNode().addControl(physic);
		GameState.BULLETAPPSTATE.getPhysicsSpace().add(physic);
		
		field.createRandomBricks();
		
		// Ground no collision
		localRootNode.attachChild(field.getNodeGround());
	}
	
	private void initPlayers() {
		playerList = new ArrayList<Player>();
		playerList.add(new Player(2, FIELDSIZE -1, 1, field));
		playerList.add(new Player(FIELDSIZE - 1, 2, 2, field));
		if(PLAYERNUMBER >= 3) {
			playerList.add(new Player(FIELDSIZE - 1, FIELDSIZE - 1, 3, field));
		}
		if(PLAYERNUMBER == 4) {
			playerList.add(new Player(2, 2, 4, field));
		}
		for(int i = 0; i < playerList.size(); i++) {
			localRootNode.attachChild(playerList.get(i).getNode());
		}
	}
	
	public void update(float delta) {
		for(int i = 0; i < playerList.size(); i++) {
			playerList.get(i).update(delta);
			if(playerList.get(i).isDead()) {
				playerList.get(i).getPhysic().destroy();
				playerList.get(i).getNode().removeFromParent();
				playerList.remove(i);
			}
		}
		field.update(delta);
		
		// GAME OVER
		if(playerList.size() == 1) {
			field.boxList.clear();
			field.getNode().removeFromParent();
			GameState.BULLETAPPSTATE.getPhysicsSpace().destroy();
			GameState.INPUTMANAGER.clearMappings();
			playerList.clear();
			
			//menu
			stateManager.detach(Bomber.GAMESTATE);
			stateManager.attach(Bomber.MENUSTATE);
		}
	}
	
	public void stateAttached(AppStateManager stateManger) {
		rootNode.attachChild(localRootNode);
		guiNode.attachChild(localGuiNode);
		
		initField();
		initPlayers();
	}
	
	public void stateDetached(AppStateManager stateManager) {
		rootNode.detachChild(localRootNode);
		guiNode.detachChild(localGuiNode);
	}
}
